home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / plnk081.zip / pilot-link.0.8.1 / libsock / datebook.c < prev    next >
C/C++ Source or Header  |  1997-08-08  |  8KB  |  359 lines

  1. /* datebook.c:  Translate Pilot datebook data formats
  2.  *
  3.  * Copyright (c) 1996, Kenneth Albanowski
  4.  *
  5.  * This is free software, licensed under the GNU Public License V2.
  6.  * See the file COPYING for details.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "pi-source.h"
  13. #include "pi-socket.h"
  14. #include "pi-dlp.h"
  15. #include "pi-datebook.h"
  16.  
  17. char * DatebookAlarmTypeNames[] =
  18.     { "Minutes", "Hours", "Days", NULL };
  19.  
  20. char * DatebookRepeatTypeNames[] =
  21.     { "None", "Daily", "Weekly", "MonthlyByDay", "MonthlyByDate", "Yearly", NULL };
  22.  
  23. /* dom1stSun = REM Sun 1  
  24.  dom1stMon = Rem Mon 1 
  25.  dom2ndSun = REM Sun 8 
  26.  domLastSun = REM Sun 1 -7*/
  27.  
  28. void free_Appointment(struct Appointment * a) {
  29.   if(a->exception)
  30.     free(a->exception);
  31.   if(a->description)
  32.     free(a->description);
  33.   if(a->note)
  34.     free(a->note);
  35. }
  36.  
  37. int unpack_Appointment(struct Appointment * a, unsigned char * buffer, int len) {
  38.   int iflags;
  39.   unsigned char * p2;
  40.   unsigned long d;
  41.   int j;
  42.   int destlen;
  43.   
  44.   /* Note: There are possible timezone conversion problems related to the
  45.            use of the begin, end, repeatEnd, and exception[] members of a
  46.            struct Appointment. As they are kept in local (wall) time in
  47.            struct tm's, the timezone of the Pilot is irrelevant, _assuming_
  48.            that any UNIX program keeping time in time_t's converts them to
  49.            the correct local time. If the Pilot is in a different timezone
  50.            than the UNIX box, it may not be simple to deduce that correct
  51.            (desired) timezone.
  52.            
  53.            The easiest solution is to keep apointments in struct tm's, and
  54.            out of time_t's. Of course, this might not actually be a help if
  55.            you are constantly darting across timezones and trying to keep
  56.            appointments.
  57.                                                                     -- KJA
  58.            */
  59.   
  60.   destlen = 8;
  61.   if (len<destlen)
  62.     return 0;
  63.   
  64.   a->begin.tm_hour = get_byte(buffer);
  65.   a->begin.tm_min = get_byte(buffer+1);
  66.   a->begin.tm_sec = 0;
  67.   d = (unsigned short int)get_short(buffer+4);
  68.   a->begin.tm_year = (d >> 9) + 4;
  69.   a->begin.tm_mon = ((d >> 5) & 15) - 1;
  70.   a->begin.tm_mday = d & 31;
  71.   a->begin.tm_isdst = -1;
  72.   a->end = a->begin;
  73.  
  74.   a->end.tm_hour = get_byte(buffer+2);
  75.   a->end.tm_min = get_byte(buffer+3);
  76.     
  77.   if(get_short(buffer) == 0xffff) {
  78.     a->event = 1;
  79.     a->begin.tm_hour = 0;
  80.     a->begin.tm_min = 0;
  81.     a->end.tm_hour = 0;
  82.     a->end.tm_min = 0;
  83.   } else {
  84.     a->event = 0;
  85.   }
  86.   
  87.   mktime(&a->begin);
  88.   mktime(&a->end);
  89.       
  90.   iflags = get_byte(buffer+6);
  91.  
  92.   /* buffer+7 is gapfil */
  93.     
  94.     p2 = (char*)buffer+8;
  95.     
  96. #define alarmFlag 64
  97. #define repeatFlag 32
  98. #define noteFlag 16
  99. #define exceptFlag 8
  100. #define descFlag 4
  101.     
  102.     if (iflags & alarmFlag) 
  103.         {
  104.         a->alarm = 1;
  105.         a->advance = get_byte(p2);
  106.         p2+=1;
  107.         a->advanceUnits = get_byte(p2);
  108.         p2+=1;
  109.         
  110.         }
  111.     else {
  112.         a->alarm = 0;
  113.         a->advance = 0;
  114.         a->advanceUnits = 0;
  115.     }
  116.         
  117.     if (iflags & repeatFlag)
  118.         {
  119.         int i,    on;
  120.         a->repeatType = get_byte(p2); p2+=2;
  121.         d = (unsigned short int)get_short(p2); p2+=2;
  122.         if(d==0xffff)
  123.             a->repeatForever=1; /* repeatEnd is invalid */
  124.         else {
  125.             a->repeatEnd.tm_year = (d >> 9) + 4;
  126.             a->repeatEnd.tm_mon = ((d >> 5) & 15) - 1;
  127.             a->repeatEnd.tm_mday = d & 31;
  128.             a->repeatEnd.tm_min = 0;
  129.             a->repeatEnd.tm_hour = 0;
  130.             a->repeatEnd.tm_sec = 0;
  131.             a->repeatEnd.tm_isdst = -1;
  132.             mktime(&a->repeatEnd);
  133.             a->repeatForever = 0;
  134.         }
  135.         a->repeatFrequency = get_byte(p2); p2++;
  136.         on = get_byte(p2); p2++;
  137.         a->repeatDay = 0;
  138.         for(i=0;i<7;i++)
  139.             a->repeatDays[i] = 0;
  140.             
  141.         if (a->repeatType == repeatMonthlyByDay)
  142.             a->repeatDay = on;
  143.         else if (a->repeatType == repeatWeekly)
  144.             for(i=0;i<7;i++)
  145.                 a->repeatDays[i] = !!(on & (1<<i));
  146.         a->repeatWeekstart = get_byte(p2); p2++;
  147.         p2++;
  148.         }
  149.     else {
  150.         int i;
  151.         a->repeatType = 0;
  152.         a->repeatForever = 1; /* repeatEnd is invalid */
  153.         a->repeatFrequency = 0;
  154.         a->repeatDay = 0;
  155.         for(i=0;i<7;i++)
  156.           a->repeatDays[i] = 0;
  157.         a->repeatWeekstart = 0;
  158.     }
  159.  
  160.     if (iflags & exceptFlag)
  161.         {
  162.         a->exceptions = get_short(p2);p2+=2;
  163.         a->exception = malloc(sizeof(struct tm)*a->exceptions);
  164.         
  165.         for(j=0;j<a->exceptions;j++,p2+=2) {
  166.             d = (unsigned short int)get_short(p2);
  167.             a->exception[j].tm_year = (d >> 9) + 4;
  168.             a->exception[j].tm_mon = ((d >> 5) & 15) - 1;
  169.             a->exception[j].tm_mday = d & 31;
  170.             a->exception[j].tm_hour = 0;
  171.             a->exception[j].tm_min = 0;
  172.             a->exception[j].tm_sec = 0;
  173.             a->exception[j].tm_isdst = -1;
  174.             mktime(&a->exception[j]);
  175.         }
  176.         
  177.         }
  178.     else  {
  179.         a->exceptions = 0;
  180.         a->exception = 0;
  181.     }
  182.  
  183.     if (iflags & descFlag)
  184.     {
  185.         a->description = strdup(p2);
  186.         p2 += strlen(p2) + 1;
  187.     } else
  188.         a->description = 0;
  189.  
  190.     if (iflags & noteFlag)
  191.     {
  192.         a->note = strdup(p2);
  193.         p2 += strlen(p2) + 1;
  194.     }
  195.     else {
  196.         a->note = 0;
  197.     }
  198.   return (p2-buffer);
  199. }
  200.  
  201. int pack_Appointment(struct Appointment *a,
  202.                       unsigned char *buf,
  203.                       int len)
  204. {
  205.     int iflags;
  206.     char *pos;
  207.     int destlen = 8;
  208.     
  209.     if (a->alarm)
  210.       destlen+=2;
  211.     if (a->repeatType)
  212.       destlen+=8;
  213.     if (a->exceptions)
  214.       destlen+=2+2*a->exceptions;
  215.     if (a->note)
  216.       destlen+=strlen(a->note)+1;
  217.     if (a->description)
  218.       destlen+=strlen(a->description)+1;
  219.     
  220.     if (!buf)
  221.       return destlen;
  222.     if (len<destlen)
  223.       return 0;
  224.  
  225.     set_byte(buf, a->begin.tm_hour);
  226.     set_byte(buf+1, a->begin.tm_min);
  227.     set_byte(buf+2, a->end.tm_hour);
  228.     set_byte(buf+3, a->end.tm_min);
  229.     set_short(buf+4, ((a->begin.tm_year - 4) << 9) |
  230.               ((a->begin.tm_mon  + 1) << 5) |
  231.               a->begin.tm_mday);
  232.     
  233.     if (a->event)
  234.     {
  235.         set_long(buf, 0xffffffff);
  236.     }
  237.  
  238. #define alarmFlag 64
  239. #define repeatFlag 32
  240. #define noteFlag 16
  241. #define exceptFlag 8
  242. #define descFlag 4
  243.  
  244.     iflags = 0;
  245.     
  246.     pos = (char *)buf + 8;
  247.  
  248.     if (a->alarm)
  249.     {
  250.         iflags |= alarmFlag;
  251.         
  252.         set_byte(pos, a->advance);
  253.         set_byte(pos+1, a->advanceUnits);
  254.         pos+=2;
  255.     }
  256.     
  257.     if (a->repeatType) {
  258.         int on,i;
  259.  
  260.         iflags |= repeatFlag;
  261.         
  262.         if (a->repeatType == repeatMonthlyByDay)
  263.             on = a->repeatDay;
  264.         else if (a->repeatType == repeatWeekly) {
  265.             on = 0;
  266.         for (i=0;i<7;i++)
  267.              if (a->repeatDays[i])
  268.                  on |= 1<<i;
  269.     } else
  270.         on = 0;
  271.  
  272.         set_byte(pos, a->repeatType);
  273.         set_byte(pos+1, 0);
  274.         pos+=2;
  275.         
  276.         if (a->repeatForever)
  277.             set_short(pos, 0xffff);
  278.         else
  279.             set_short(pos, ((a->repeatEnd.tm_year - 4) << 9) |
  280.                 ((a->repeatEnd.tm_mon  + 1) << 5) |
  281.                 a->repeatEnd.tm_mday);
  282.         
  283.         pos+=2;
  284.         
  285.         set_byte(pos, a->repeatFrequency); pos++;
  286.         set_byte(pos, on); pos++;
  287.         set_byte(pos, a->repeatWeekstart); pos++;
  288.         set_byte(pos, 0); pos++;
  289.     }
  290.     
  291.     if (a->exceptions) {
  292.         int i;
  293.         
  294.         iflags |= exceptFlag;
  295.         
  296.         set_short(pos, a->exceptions); pos+=2;
  297.         
  298.         for(i=0;i<a->exceptions;i++,pos+=2)
  299.             set_short(pos, ((a->exception[i].tm_year - 4) << 9) |
  300.                 ((a->exception[i].tm_mon  + 1) << 5) |
  301.                 a->exception[i].tm_mday);
  302.     }
  303.  
  304.     if (a->description != NULL)
  305.     {
  306.         iflags |= descFlag;
  307.         
  308.         strcpy(pos, a->description);
  309.         pos += strlen(pos) + 1;
  310.     }
  311.     
  312.     if (a->note != NULL)
  313.     {
  314.         iflags |= noteFlag;
  315.         
  316.         strcpy(pos, a->note);
  317.         pos += strlen(pos) + 1;
  318.     }
  319.  
  320.     set_byte(buf+6, iflags);
  321.     set_byte(buf+7, 0); /* gapfil */
  322.  
  323.     return ((long)pos - (long)buf);
  324. }
  325.  
  326.                   
  327. int unpack_AppointmentAppInfo(struct AppointmentAppInfo * ai, unsigned char * record, int len) {
  328.   int i;
  329.   i = unpack_CategoryAppInfo(&ai->category, record, len);
  330.   if (!i)
  331.     return 0;
  332.   record += i;
  333.   len -= i;
  334.   if (len<2)
  335.     return 0;
  336.   ai->startOfWeek = get_byte(record);
  337.   return i+2;
  338. }
  339.  
  340. int pack_AppointmentAppInfo(struct AppointmentAppInfo * ai, unsigned char * record, int len) {
  341.   int i;
  342.   unsigned char * start = record;
  343.   
  344.   i = pack_CategoryAppInfo(&ai->category, record, len);
  345.   if (!record)
  346.     return i+2;
  347.   if (!i)
  348.     return i;
  349.   record += i;
  350.   len -= i;
  351.   if (i<2)
  352.     return 0;
  353.   set_short(record, 0);
  354.   set_byte(record, ai->startOfWeek);
  355.   record+=2;
  356.   
  357.   return (record-start);
  358. }
  359.